#include <Arduino.h>
#include "mqtt.h"
#include <base64.h>
#include <Crypto.h>
#include "espcrypto.h"
#include <ArduinoJson.h>
#include <Preferences.h>
#include "espcrypto.h"
#include "config.h"
#include "mainfunc.h"
#include "blefunc.h"
#include "httpfunc.h"
#include "NTPTime.h"
#include "mainfunc.h"
#include "bucket_plant_water/bucket_plant_water.h"
#include "ESP32Time.h"
#include "ActionCtrl.h"
#include "global.h"
#include "BizUtils.h"
#include "SensorData.h"
#include "CondNotice.h"
#include "websocket.h"
#include "ntc.h"

#include "test.h"
#include "ota.h"
#include "timer.h"
#include "Log.h"

static void delayFunc(String s)
{

  if (s.equals("5"))
  {
    Serial.println("delayFunc");
    startApp(true);
    removeGlobalTimerCallBack("delayStartApp");
  }
}

static void sendDataCallBack(String time)
{

  long t = time.toInt();
  long frequency = getGlobalLocalConfig()->getTypeConfig()->getFrequencyDaytime();
  // frequency =15;
  // printStr("sendData frequency",frequency);

  if (frequency == 0)
  {
    frequency = 120;
  }
  if (t % frequency == 0)
  {

    setSendData(true);
  }
}

static void connectWiFiCallback(String s)
{
  long t = s.toInt();
  if (t % 30 == 0)
  {
    beep(true);
    delay(100);
    beep(false);
    if (!isWiFiConnected())
    {
      setNeedConnectWiFi(true);
    }
    else
    {
      setNeedConnectWiFi(false);
    }
  }
}
bool flag = false;
void delayStartFlag(String s)
{
  flag = true;
}

void resetupWiFi(String s)
{
  long i = s.toInt();
  if (i % 60 == 0)
  {
    setNeedConnectWiFi(true);
  }
}

// static void delayStart()
// {

//   int appmode = getAppMode();
//    printStr("appmode", appmode);
//     int ret = setUpWiFi();
//     printStr("setup wifi ret", ret);
//     setWiFiConnected(ret == 0); // 连接wifi 并设置状态
//     if (!isWiFiConnected()) // 联网失败
//     {
//       printStr("联网失败");
//       addGlobalTimerCallBack("connectWiFi", connectWiFiCallback); // 30s重连一次                                                          // beepTimes(2);
//     }
//     else
//     { // 联网成功
//       removeGlobalTimerCallBack("connectWiFi");
//       setNTPTime();
//       setGlobalRTCIntervalAciton();
//       printStr("联网成功");
//     }

//   addGlobalTimerCallBack("sendData", sendDataCallBack);
  
//   // if (!isAllowOfflineRun())
//     //   { // 如果不允许离线运行，并且是省电模式
//     //     setTimerWakeup(String(600));
//     //     setSleepMode(GPIO_TIMER_MODE);
//     //     startSleep(0);
//     //   }

// }
TimerActionB *tab;
void pumpFinishCallback(void *data)
{

  if (tab == nullptr)
  {
    return;
  }
  // TimerActionB *a = static_cast<TimerActionB *>(data);
  String tip = "间隔定时任务，" + tab->action->name + String(tab->getDuration()) + String("秒");

  tip += "执行成功";
  addNotice("间隔定时任务", tip, "", "3", 0);
  tab = nullptr;
}

void intervalAction(void *data)
{
  TimerActionB *a = static_cast<TimerActionB *>(data);
  printStr("间隔模式 intervalTime", a->getIntervalTime());
  printStr("间隔时长  ", a->getDuration());
  printStr("actionID->  ", a->action->id);
  if (a == nullptr)
  {
    return;
  }
  if (a->action->id.equals("pump"))
  {
    printStr("开始pump");
    // setGlobalSleepdelayTime(a->getDuration());
    if (getCurrentVcc() <= 0.3)
    {
      String tip = "间隔定时任务，" + a->action->name + String(a->getDuration()) + String("秒,");
      tip += String("电量不足，执行失败");
      addNotice("间隔定时任务", tip, "", "3", 0);
      return;
    }
    if (!isWater())
    {
      String tip = "间隔定时任务，" + a->action->name + String(a->getDuration()) + String("秒,");
      tip += String("缺水，执行失败");
      addNotice("间隔定时任务", tip, "", "3", 0);
      return;
    }
    pumpTime(a->getDuration());
    tab = a;
    addGlobalFuncCallBack("pumpFinish", pumpFinishCallback);

    setGlobalSleepdelayTime(getTotalPumpTime() + 10);
  }
}

void singleAction(void *data)
{
  TimerActionA *a = static_cast<TimerActionA *>(data);
  printStr("单次定时模式 actionTime", a->actionTime);
  if (a == nullptr)
  {
    return;
  }
  if (a->action->id.equals("pump"))
  {
    pumpTime(a->getDuration());

    String tip = "单次定时任务触发，" + a->action->name + String(a->getDuration()) + String("秒");
    addNotice("单次定时任务触发", tip, "", "3", 0);
    setGlobalSleepdelayTime(getTotalPumpTime());
  }
}

void weekAction(void *data)
{
  TimerActionA *a = static_cast<TimerActionA *>(data);
  printStr("周期定时模式 actionTime", a->actionTime);
  if (a == nullptr)
  {
    return;
  }
  if (a->action->id.equals("pump"))
  {
    pumpTime(a->getDuration());

    String tip = "周期定时任务触发，" + a->action->name + String(a->getDuration()) + String("秒");
    addNotice("周期定时任务触发", tip, "", "3", 0);
    setGlobalSleepdelayTime(getTotalPumpTime());
  }
}

void ctrlLightCB(String i)
{
  ctrlLight();
}

void excuteTimerActionCB(String i)
{
   excuteTimerAction();
}


#define uS_TO_S_FACTOR 1000000ULL
void setupMainBPW()
{
  Serial.begin(9600);
  Serial.println("setupMainBPW");
 // clearPreference();
  setDeviceType("bucket_water_v1");
  initPortBPW();
  light("b",true);

 
  //closeRGB();
  pump(false);
  beep(false);
  //checkLowPowerBoot();//测试暂时注释掉
  print_wakeup_reason();
  setBeepTriggerLevel(0);
  setCanDisablePump(false);
  attachButtonClick();
  config();
  printStr("env:", getEnv());
  setupWatchDog();
 
  if (!isActive())
  {
    attachGlobalTimer();

    blink("b", 60 * 10);

    setSleepMode(GPIO_MODE);
    startSleep(60 * 100); // 十分钟后未连接就休眠
    
    setupBle();
    startAdvertising();
    return;//这里必须返回
  }
  attachGlobalTimer();
  setupTicker();
  parseFromPreference(); // 没有激活不要触发定时任务
  setupCrypto();
  if (isHasUpgrade())
  {
    printStr("有新版本升级");
    setUpWiFi();
    updateOTA();
    return;
  }
  printStr("start app enter main app");
 // getGlobalLocalConfig()->print();
  //  int appmode = getAppMode();
  //  printStr("appmode", appmode);
    int ret = setUpWiFi();
    printStr("setup wifi return value", ret);
    setWiFiConnected(ret == 0); // 连接wifi 并设置状态
    if (!isWiFiConnected()) // 联网失败
    {
      printStr("联网失败");
      addGlobalTimerCallBack("connectWiFi", connectWiFiCallback); // 30s重连一次                                                          // beepTimes(2);
    }
    else
    { // 联网成功
      removeGlobalTimerCallBack("connectWiFi");
     // setGlobalRTCIntervalAciton();
      printStr("联网成功");
    }

    if(isBootByWakeup()){
      setRTCNTPTime();
    }else{
      setNTPTime();
       putLog(EXCEPTION_REBOOT,getRtcTime().getEpoch(),"");
    }
   
    addGlobalTimerCallBack("sendData", sendDataCallBack);

  // if (!isAllowOfflineRun())
    //   { // 如果不允许离线运行，并且是省电模式
    //     setTimerWakeup(String(600));
    //     setSleepMode(GPIO_TIMER_MODE);
    //     startSleep(0);
    //   }
  addGlobalFuncCallBack("singleAction", singleAction);
  addGlobalFuncCallBack("intervalAction", intervalAction);
  addGlobalFuncCallBack("weekAction", weekAction);
  setupSensorData(); // 检测是否空转，有水，缺水,定时
  setupCondNotice();
  setupNTC();

  if (isWiFiConnected() && isActive())
  {
    setupWS();
    if (!connectWS())
    {
      printStr("connectWS 连接失败");
    }
  }
  else
  {
    printStr("wifi未连接或未激活");
  }
  setDisableLight(!getGlobalLocalConfig()->getIndicatorLight());
  setDisableBeep(!getGlobalLocalConfig()->getBeep());

  blink("g", 60 * 60 * 24);
  // setupMQTT();
  // sendNotice();
  setAppReady(true);
  setClickButtonLight();
  addGlobalTimerCallBack("ctrlLight", ctrlLightCB);
  addGlobalTimerCallBack("excuteTimerAction", excuteTimerActionCB);
  sendDataBPW();
}

void pumpOverloadCb1(String i)
{
  setPumpPause(false);
}

int overloadTimes = 0;

void checkPumpOverloadRealTime()
{
  if (!isPumpStop() || isPumpContinue())
  {
    float vccPinAvr = getSensorPinValue("vcc");
    float currentVcc = getVccPinValue();
    float diffVcc = currentVcc - vccPinAvr;

    if (diffVcc < -520)
    {
      printStr("diffVcc", diffVcc);
      setPumpPause(true);
      excuteDelay(5, "pumpoverload", pumpOverloadCb1);
      overloadTimes++;
      if (overloadTimes >= 3)
      {
        addOverloadNotice();
      }
    }
  }
}

int max(int a, int b)
{
  return (a > b) ? a : b;
}
bool isReadySleepVal = false;

void pumpOverloadCallback(String i){
  setPumpOverload(false);
}
void loopMainBPW()
{
   feedWatchDog();

  checkPumpOverloadRealTime();

       
 // 检测水泵是否过载
    bool isOverload = checkPumpOverload();
  
    if (isOverload && (!isPumpOverload()))
    {
        
        switchPump();//暂时去掉，测试
        printStr("水泵过载");
        setPumpOverload(true);
       // addOverloadNotice();
       excuteDelay(5,"overload1",pumpOverloadCallback);
    }

  loopArduinoOTA();
  loopMain();
  loopWS();
  ctrlPump();
  if(!isActive()){
    return;
  }


  if (!isPumpContinue())
  {
    // 实时监测
    sendNotice();
    sendCachePost();
  }

  if (isSendPing() && isWiFiConnected())
  {
    sendPing();
    setSendPing(false);
  }

  //excuteTimerAction();
  if (isSendData())
  {
    printStr("sendData");
    sendDataBPW();
    setSendData(false);
    printStr("数据发送完毕");
    if (isHasUpgrade())
    {
      printStr("有新版本升级");
      setUpWiFi();
      updateOTA();
      return;
    }
  }

  if (getAppMode() == 2&& isReadySleepVal==false)
  {
    light("g", true);
    // setUpWiFi();
    // setNTPTime();
    // sendDataBPW();
    // setSendData(true);
    setSleepMode(GPIO_TIMER_MODE);
    long delayTime =  getTotalPumpTime()+30;
    if (getWakeupReason() == ESP_SLEEP_WAKEUP_GPIO)
    {
      delayTime = max(delayTime, 300);
    }
    if (delayTime == 0)
    {
      delayTime = 5;
    }
    printStr("delay sleep time", delayTime);
    sendDataBPW();
    startSleep(delayTime); // 唤醒的间隔时间从typeconfig中设置
    isReadySleepVal = true;
  }
}
